import os
import logging
import time
import pandas as pd

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

from config import DRIVER_PATH, LOGIN_URL
from crawler.browser import Browser

logging.basicConfig(format='[%(levelname)s] %(message)s', level=logging.INFO)

STEPS = [
    "Launch browser",
    "Open login page",
    "Switch to username/password tab",
    "Fill in credentials",
    "Submit login and solve CAPTCHA",
    "Handle post-login notification",
    "Navigate to 教学平台",
    "Select course",
    "Select submission node",
    "Load submission details",
    "Set status filter",
    "Extract submissions",
    "Close browser",
]

def mark(step_index):
    logging.info(f"[{step_index+1}/{len(STEPS)}] {STEPS[step_index]}")


def main():
    # Read credentials from environment
    username = os.getenv("KKW_USERNAME")
    password = os.getenv("KKW_PASSWORD")
    if not username or not password:
        raise RuntimeError("Please set KKW_USERNAME and KKW_PASSWORD environment variables")

    # 1) launch browser
    mark(0)
    browser = Browser(driver_path=DRIVER_PATH, headless=False)
    wait = WebDriverWait(browser.driver, 15)

    try:
        # 2) open login page
        mark(1)
        browser.open_url(LOGIN_URL)

        # 3) switch to username/password tab
        mark(2)
        pwd_tab = wait.until(EC.element_to_be_clickable(
            (By.CSS_SELECTOR, "span[onclick='loginForPwd()']")
        ))
        pwd_tab.click()

        # 4) fill in credentials
        mark(3)
        user_el = wait.until(EC.element_to_be_clickable((By.ID, "username")))
        user_el.clear()
        user_el.send_keys(username)
        pass_el = wait.until(EC.element_to_be_clickable((By.ID, "pwd")))
        pass_el.clear()
        pass_el.send_keys(password)
        print()

        # 5) submit login and solve CAPTCHA
        mark(4)
        login_btn = wait.until(EC.element_to_be_clickable(
            (By.CSS_SELECTOR, "button[onclick='logincheck()']")
        ))
        login_btn.click()
        if not browser.solve_slider(
            slider_handle=(By.CSS_SELECTOR, ".code-btn-img.code-btn-m")
        ):
            raise RuntimeError("Slider solve failed")
        # Wait for login redirect
        wait.until(lambda d: d.current_url != LOGIN_URL)
        time.sleep(1)

        # 6) handle post-login notification
        mark(5)
        browser.close_notification_popup()

        # 7) navigate to 教学平台
        mark(6)
        teach_link = wait.until(EC.element_to_be_clickable((By.LINK_TEXT, "教学平台")))
        teach_link.click()
        wait.until(EC.url_contains("#/curriculumSpace"))
        browser.close_notification_popup()

        # 8) select the course
        mark(7)
        course_suffix = "14423-软件工程-叶昕源 2024-2025_2"
        browser.select_course(course_suffix, timeout=15)
        wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "div[role='treeitem']")))

        # 9) select the submission node
        mark(8)
        browser.select_submission("期末考试 提交处", timeout=15)

        # 10) load submission details
        mark(9)
        browser.view_submission_details(timeout=15)

        # 12) extract submissions
        mark(11)
        submissions = browser.extract_all_submissions()

        # deduplicate submissions by student_id, keeping the first occurrence
        df_subs = pd.DataFrame(submissions)
        df_subs = df_subs.drop_duplicates(subset=['student_id'], keep='first')
        submissions = df_subs.to_dict(orient='records')
        for s in submissions:
            print(f"{s['student_id']}	{s['student_name']}	{s['submit_time']}	{s['submission_url']}")

        # save all submissions to an Excel file
        df = pd.DataFrame(submissions)
        output_file = "submissions.xlsx"
        df.to_excel(output_file, index=False)
        logging.info(f"Saved {len(submissions)} submissions to {output_file}")

    finally:
        # 13) close browser
        mark(12)
        browser.close()

if __name__ == "__main__":
    main()
